/*
 * VM_Arena.h
 *
 *  Created on: Jan 25, 2010
 *      Author: dhovemey
 */

#ifndef VM_SEMISPACE_H_
#define VM_SEMISPACE_H_

#include <cstddef>
#include "interp/VM_Object.h"
class VM_Class;

/**
 * Arena from which VM_Objects are allocated.
 */
class VM_Arena {
private:
	VM_Object *m_data;
	size_t m_size;
	VM_Object *m_freelist;
#ifndef NDEBUG
	unsigned m_numObjectsAllocated;
	unsigned m_numObjectsReclaimed;
#endif

	VM_Arena(const VM_Arena &other);
	VM_Arena& operator=(const VM_Arena &rhs);

public:
	/**
	 * Constructor.
	 *
	 * @param size number of objects in the arena
	 */
	VM_Arena(size_t size);

	/** Destructor. */
	~VM_Arena();

	VM_Object *alloc(VM_Class *vmCls);

	// for scanning through allocated objects

	/**
	 * Return a pointer to the first VM_Object in the arena.
	 */
	VM_Object *first();

	/**
	 * Given a pointer to a VM_Object in the arena,
	 * return a pointer to the next one.
	 *
	 * @param obj a VM_Object
	 * @return pointer to the next VM_Object in the arena
	 */
	VM_Object *next(VM_Object *obj);

	/**
	 * Clear the marks from all objects in the arena.
	 */
	void clearMarks();

	/**
	 * Based on the initial set of marked objects, find all
	 * transitively-reachable objects.
	 */
	void findReachableObjects();

	/**
	 * De-allocate all unreachable objects.
	 */
	void sweep(VM_Interpreter *interp);

#ifndef NDEBUG
	unsigned getNumObjectsAllocated() { return m_numObjectsAllocated; }
	unsigned getNumObjectsReclaimed() { return m_numObjectsReclaimed; }

	void *memStart() { return m_data; }
	void *memEnd() { return m_data + m_size; }
#endif

private:
	VM_Object *buildFreelist();
};

#endif /* VM_SEMISPACE_H_ */
